﻿
Imports System.IO
Imports std
Imports storoomc
Imports xmlctrl
Imports rssctrl

Public Class rssrequest
    Inherits cacheControlProcessor
    'handle /rss?tag=abc, render rss items with tag mark

    Public Const maxRndCount As Int64 = 4
    Public Const _pathidentity As String = "/rss"

    Public Class query
        Public Const tag As String = "tag"
        Public Const rnd As String = "rnd"
    End Class

    Public Overrides Function pathidentity() As String
        Return _pathidentity
    End Function

    Public Overrides Function pathidentitylen() As Long
        Return strlen(pathidentity())
    End Function

    Protected Overrides Function retiredticks() As Int64
        Return 10 * 60 * 1000 * 1000
    End Function

    Protected Overrides Sub addresponseHeaders(ByVal context As httpContext)
        MyBase.addresponseHeaders(context)
        context.setcontentType(network.http.contentType.rssxml)
    End Sub

    Protected Overloads Overrides Function processImpl(ByVal context As httpContext _
                                                       , ByRef control As xmlcontrol) As Boolean
        Dim tag As String = Nothing
        tag = context.url.query(query.tag)
        Dim rndCount As Int64
        If context.url.query.find(query.rnd) <> context.url.query.end() Then
            If Not convertor.toint64(context.url.query(query.rnd), rndCount) Then
                raiseError("do not get available rnd <" + context.url.query(query.rnd) + "> parameter from url, " _
                           + "use default value.", errorHandle.errorType.warning)
                rndCount = maxRndCount
            ElseIf rndCount > maxRndCount OrElse rndCount <= 0 Then
                raiseError("got rnd over bound " + context.url.query(query.rnd) + ", use default random value.")
                rndCount = rnd(1, maxRndCount, True)
            End If
        Else
            rndCount = rnd(1, maxRndCount, True)
        End If

        Dim buff As MemoryStream = Nothing
        buff = context.buff()
        Dim page As rsspage = Nothing
        page = New rsspage(buff)
        page.title().text = applicationSign() + " - rss result"
        Dim bytes As bytes = Nothing
        Dim i As Int64

        Dim tags As vector(Of String) = Nothing
        If isemptystring(tag) Then
            If Not storoom.read(rashare.tagsname, bytes) Then
                raiseError("cannot get tags list, ignore request.", errorHandle.errorType.warning)
                Return False
            End If

            Dim temp As vector(Of String) = Nothing
            strsepar(encoding.utf8.GetString(bytes.data), spaceChars, temp, True)
            tags = New vector(Of String)
            For i = 0 To min(rndCount, temp.size() - 1)
                Dim sel As Int64
reselect:
                sel = rnd(0, temp.size(), True)
                If tags.find(temp(sel)) <> npos Then
                    GoTo reselect
                End If
                tags.push_back(temp(sel))
            Next
        Else
            strsepar(tag, spaceChars, tags, True)
        End If

        Dim feeds As [set](Of String) = Nothing
        feeds = New [set](Of String)()
        For i = 0 To tags.size() - 1
            If Not storoom.read(tags(i), bytes) Then
                raiseError("cannot read feeds from tag " + tags(i) + ", ignore this tag.", errorHandle.errorType.warning)
            Else
                Dim cur As vector(Of String) = Nothing
                strsepar(encoding.utf8.GetString(bytes.data), character.newline, cur, True)
                Dim j As Int64
                For j = 0 To cur.size() - 1
                    kickNewlineChar(cur(j))
                    feeds.insert(cur(j))
                Next
            End If
        Next

        Dim it As [set](Of String).iterator = Nothing
        it = feeds.begin()
        While it <> feeds.end()
            If Not storoom.read((+it), bytes) Then
                raiseError("cannot read items from feed " + (+it) + ", ignore this feed." _
                           , errorHandle.errorType.warning)
            Else
                page.channel().text += encoding.utf8.GetString(bytes.data)
            End If
            it += 1
        End While

        control = page
        Return True
    End Function
End Class
